#include <iostream>
#include <sys/eventfd.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <sys/un.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>

void unix_socket_server()
{
    int server_sockfd, client_sockfd;
    int server_len, client_len;
    struct sockaddr_un server_address;
    struct sockaddr_un client_address;
    int i, byte;
    char ch_send, recv_buf[1024];

    unlink("/tmp/test"); //解除原有server_socket对象链接
    server_sockfd = socket(AF_UNIX, SOCK_STREAM, 0); //创建socket，指定通信协议为AF_UNIX,数据方式SOCK_STREAM
    std::cout << "server_sockfd:" << server_sockfd << std::endl;
    //配置server_address
    server_address.sun_family = AF_UNIX;
    strcpy(server_address.sun_path, "/tmp/test");
    server_len = sizeof(server_address);

    int result = bind(server_sockfd, (struct sockaddr *)&server_address, server_len);
    std::cout << result << std::endl;

    result = listen(server_sockfd, 5);
    std::cout << result << std::endl;
    std::cout << "server waiting for  client connect" << std::endl;
    client_len = sizeof(client_address);
    // accept函数接收客户端求情，存储客户端地址信息、客户端地址大小
    while (true) {
        client_sockfd = accept(server_sockfd, (struct sockaddr *)&client_address, (socklen_t *)&client_len);
        std::cout << "the server wait form client data" << std::endl;

        while (true) {
            memset(recv_buf, 0, sizeof(recv_buf));
            //从client_sockfd读取客户端发来的消息
            if ((byte = read(client_sockfd, recv_buf, sizeof(recv_buf))) == -1) {
                perror("read");
                exit(EXIT_FAILURE);
            }
            if (byte == 0) {
                break;
            }
            std::cout << "the massage receiver from client is: " << recv_buf << std::endl;
            std::string sendMsg = "ok";
            //向客户端发送消息
            uint32_t len = htonl((uint32_t)sendMsg.size()); // 转网络字节序
            if (write(client_sockfd, &len, sizeof(uint32_t)) < 0) {
                break;
            }

            if ((byte = write(client_sockfd, sendMsg.c_str(), sendMsg.length())) == -1) {
                perror("write");
                exit(EXIT_FAILURE);
            }
            break;
        }

        std::cout << "clost socket:" << close(client_sockfd) << std::endl;
    }
    unlink("/tmp/test");
}
int main(int argc, char **argv)
{
    unix_socket_server();
    return 0;
}
